package com.springboot.cloud.demos.producer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.springboot.cloud.common.core.constant.Constant;
import com.springboot.cloud.common.core.entity.vo.Result;
import com.springboot.cloud.common.core.util.DateUtils;
import com.springboot.cloud.demos.entity.enums.MomentType;
import com.springboot.cloud.demos.entity.param.AlbumQueryParam;
import com.springboot.cloud.demos.entity.param.MomentQueryParam;
import com.springboot.cloud.demos.entity.po.Album;
import com.springboot.cloud.demos.entity.po.Moment;
import com.springboot.cloud.demos.producer.dao.MomentMapper;
import com.springboot.cloud.demos.producer.service.IAlbumService;
import com.springboot.cloud.demos.producer.service.IMomentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@RefreshScope
public class MomentServiceImpl extends ServiceImpl<MomentMapper, Moment> implements IMomentService {

    @Resource
    private IAlbumService albumService;

    @Override
    @CacheEvict(value = "moment", allEntries = true)
    public boolean add(Moment moment) {
        return this.save(moment);
    }


    @Override
    public boolean delete(String id) {
        return this.removeById(id);
    }

    @Override
    public IPage<Map<String, Object>> nearbyList(Integer sex, Integer real, Integer pretty, float longitude, float latitude, Integer pageNo, Integer pageSize) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if (sex != null) {
            queryWrapper.eq("c.sex", sex);
        }
        if (sex != null) {
            queryWrapper.eq("c.real_man", real);
        }
        if (sex != null) {
            queryWrapper.eq("c.pretty", pretty);
        }
        queryWrapper.orderByDesc("a.created_time");
        queryWrapper.eq("deleted", "N");
        Page page = new Page<>(pageNo, pageSize);
        IPage<Map<String, Object>> pageResult = getBaseMapper().nearbyList(page, queryWrapper, latitude, longitude);
        buildResult(pageResult);
        return pageResult;
    }

    @Override
    public IPage<Map<String, Object>> broadcastList(Integer sex, Integer real, Integer pretty, Integer type, Integer pageNo, Integer pageSize) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if (sex != null) {
            queryWrapper.eq("c.sex", sex);
        }
        if (sex != null) {
            queryWrapper.eq("c.real_man", real);
        }
        if (sex != null) {
            queryWrapper.eq("c.pretty", pretty);
        }
        if (type != null) {
            queryWrapper.eq("a.type", type);
        }
        queryWrapper.eq("deleted", "N");
        queryWrapper.orderByDesc("a.created_time");
        Page page = new Page<>(pageNo, pageSize);
        IPage<Map<String, Object>> pageResult = getBaseMapper().broadcastList(page, queryWrapper);
        buildResult(pageResult);
        return pageResult;
    }

    @Override
    public IPage<Map<String, Object>> recommendList(String userId, Integer sex, Integer real, Integer pretty, Integer pageNo, Integer pageSize) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if (sex != null) {
            queryWrapper.eq("c.sex", sex);
        }
        if (sex != null) {
            queryWrapper.eq("c.real_man", real);
        }
        if (sex != null) {
            queryWrapper.eq("c.pretty", pretty);
        }
        queryWrapper.orderByDesc("a.created_time");
        queryWrapper.eq("deleted", "N");
        Page page = new Page<>(pageNo, pageSize);
        IPage<Map<String, Object>> pageResult = getBaseMapper().recommendList(page, queryWrapper);
        buildResult(pageResult);
        return pageResult;
    }

    private void buildResult(IPage<Map<String, Object>> pageResult) {
        for (Map<String, Object> map : pageResult.getRecords()) {
            // 查询album
            String momentId = map.get("id").toString();
            buildMapResult(momentId, map);
        }
    }

    @Override
    public IPage<Map<String, Object>> followList(String userId, Integer sex, Integer real, Integer pretty, Integer pageNo, Integer pageSize) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if (sex != null) {
            queryWrapper.eq("c.sex", sex);
        }
        if (sex != null) {
            queryWrapper.eq("c.real_man", real);
        }
        if (sex != null) {
            queryWrapper.eq("c.pretty", pretty);
        }
        queryWrapper.eq("d.user_id", userId);
        queryWrapper.eq("deleted", "N");
        queryWrapper.orderByDesc("a.created_time");
        Page page = new Page<>(pageNo, pageSize);
        IPage<Map<String, Object>> pageResult = getBaseMapper().followList(page, queryWrapper);
        buildResult(pageResult);
        return pageResult;
    }

    @Override
//    @Cacheable(value = "moment", key = "#root.targetClass+'-list-'+'-'+#userQueryForm.userId+#userQueryForm.pageNo+'-'+#userQueryForm.pageSize")
    public IPage<Map<String, Object>> list(String userId, Integer type, Integer pageNo, Integer pageSize) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("deleted", "N");
        if (type != null) {
            queryWrapper.eq("a.type", type);
        }
        queryWrapper.orderByDesc("a.created_time");
        Page page = new Page<>(pageNo, pageSize);
        IPage<Map<String, Object>> pageResult = getBaseMapper().selectMapsPage(page, queryWrapper);
        buildResult(pageResult);
        return pageResult;
    }

    @Override
    @Cacheable(value = "moment", key = "#root.targetClass+'-getMomentMap-'+#id")
    public Map getMomentMap(String id) {

        Map map = getBaseMapper().selectMap(id);
        AlbumQueryParam queryParam = new AlbumQueryParam();
        queryParam.setMomentId(id);
        List<Album> albums = albumService.query(queryParam);
        map.put("albums", albums);
        return map;
    }

    @Override
    @Cacheable(value = "moment", key = "#root.targetClass+'-next-'+#momentId")
    public Map<String, Object> next(String momentId) {
        Moment moment = get(momentId);
        Map<String, Object> map = this.getBaseMapper().nextWidthUser(moment.getUserId(), DateUtils.formatDateTime(moment.getCreatedTime()));
        if (map == null) {
            map = this.getBaseMapper().next(DateUtils.formatDateTime(moment.getCreatedTime()));
            if (map != null) {
                buildMapResult(map.get("id").toString(), map);
            }
        }
        return map;
    }

    private void buildMapResult(String momentId, Map<String, Object> map) {
        AlbumQueryParam queryParam = new AlbumQueryParam();
        queryParam.setMomentId(momentId);
        queryParam.setDeleted("N");
        List<Album> albums = albumService.query(queryParam);
        map.put("albums", albums);
    }

    @Override
    @Cacheable(value = "moment", key = "#root.targetClass+'-prev-'+#momentId")
    public Map<String, Object> prev(String momentId) {
        Moment moment = get(momentId);
        Map<String, Object> map = this.getBaseMapper().prevWidthUser(moment.getUserId(), DateUtils.formatDateTime(moment.getCreatedTime()));
        if (map == null) {
            map = this.getBaseMapper().prev(DateUtils.formatDateTime(moment.getCreatedTime()));
        }
        if(map!=null){
            buildMapResult(map.get("id").toString(), map);
        }
        return map;
    }

    @Override
    @CacheEvict(value = "moment", allEntries = true)
    public boolean update(Moment moment) {
        return this.updateById(moment);
    }

    @Override
    @Cacheable(value = "moment", key = "#root.targetClass+'-'+#id")
    public Moment get(String id) {
        return this.getById(id);
    }

    @Override
    public List<Moment> query(MomentQueryParam param) {
        QueryWrapper<Moment> queryWrapper = param.build();
        queryWrapper.eq("user_id", param.getUserId());
        return this.list(queryWrapper);
    }


}
